package com.topcheer.common.base.util;

import com.topcheer.common.base.vo.BaseResponse;
import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletMappingDescription;
import org.springframework.boot.actuate.web.mappings.servlet.DispatcherServletsMappingDescriptionProvider;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @author xutao
 * @Package com.topcheer.common.base.util
 * @Description: ${todo}
 * @date 2020/3/31 21:56
 */
public class WebUtil {

    public static void renderMsg(HttpServletResponse response, int code, String msg) throws IOException {
        response.setContentType("application/json;charset=UTF-8");
        ServletOutputStream out = response.getOutputStream();
        String str = JsonMapper.defaultMapper().toJson(new BaseResponse<>().code(code).msg(msg));
        out.write(str.getBytes("UTF-8"));
        out.flush();
        out.close();
    }

    public static String initDescription(Class<?> beanType, Method method) {
        StringJoiner joiner = new StringJoiner(", ", "(", ")");
        Class[] var3 = method.getParameterTypes();
        int var4 = var3.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Class<?> paramType = var3[var5];
            joiner.add(paramType.getSimpleName());
        }

        return beanType.getName() + "#" + method.getName() + joiner.toString();
    }

    public static String getPatternUrl (HandlerMethod handlerMethod){
        String description = initDescription(handlerMethod.getBeanType(), handlerMethod.getMethod());
        return getMvcPattern(description);
    }

    public static List<String> getAllMvcPattern(){
        DispatcherServletsMappingDescriptionProvider bean = SpringContextUtils.getBean(DispatcherServletsMappingDescriptionProvider.class);
        Map<String, List<DispatcherServletMappingDescription>> stringListMap = bean.describeMappings(SpringContextUtils.getApplicationContext());
        for(List<DispatcherServletMappingDescription> dispatcherServletMappingDescriptions : stringListMap.values()){
            return dispatcherServletMappingDescriptions.stream().map(DispatcherServletMappingDescription::getPredicate).collect(Collectors.toList());
        }
        return null;
    }

    public static void initUrlMapping(){
        DispatcherServletsMappingDescriptionProvider bean = SpringContextUtils.getBean(DispatcherServletsMappingDescriptionProvider.class);
        Map<String, List<DispatcherServletMappingDescription>> stringListMap = bean.describeMappings(SpringContextUtils.getApplicationContext());
        for(List<DispatcherServletMappingDescription> dispatcherServletMappingDescriptions : stringListMap.values()){
            dispatcherServletMappingDescriptions.stream().forEach(dispatcherServletMappingDescription ->{
                CommonCache.putPredicate(dispatcherServletMappingDescription.getHandler(),dispatcherServletMappingDescription.getPredicate());
            });
        }
    }

    public static String getMvcPattern(String referenceName){
        if(CommonCache.isNullHandler()){
            initUrlMapping();
        }
        return CommonCache.getPredicate(referenceName);
        /*DispatcherServletsMappingDescriptionProvider bean = SpringContextUtils.getBean(DispatcherServletsMappingDescriptionProvider.class);
        Map<String, List<DispatcherServletMappingDescription>> stringListMap = bean.describeMappings(SpringContextUtils.getApplicationContext());
        for(List<DispatcherServletMappingDescription> dispatcherServletMappingDescriptions : stringListMap.values()){
            Optional<String> optional = dispatcherServletMappingDescriptions.stream().filter(description -> {
                return referenceName.equals(description.getHandler());
            }).findFirst().map(DispatcherServletMappingDescription::getPredicate);
            return optional.isPresent()?optional.get():null;
        }*/
        /*for (Map.Entry<String, List<DispatcherServletMappingDescription>> entry : stringListMap.entrySet()) {
            List<DispatcherServletMappingDescription> dispatcherServletMappingDescriptions = entry.getValue();
            dispatcherServletMappingDescriptions.stream().forEach(description -> {
                if (referenceName.equals(description.getHandler())) {
                    result[0] = description.getPredicate();
                }
            });
        }*/
    }

}
